<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <title>移动图片</title>
    <script src="js/animate.js"></script>
    <style type="text/css">

    * {
        margin: 0;
        padding: 0;
    }
    
    #photo {
        width: 680px;
        height: 680px;
        margin: 100px auto;
    }
    
    #photo ul {
        width: 100%;
    }
    
    #photo ul li {
        list-style: none;
        float: left;
        margin: 10px;
        width: 200px;
        height: 200px;
        border: 2px solid transparent;
    }
    
    #photo ul li img {
        width: 200px;
        height: 200px;
    }
    </style>
</head>

<body>
    <div id="photo">
        <ul>
            <li><img src="images/1.jpg"></li>
            <li><img src="images/2.jpg"></li>
            <li><img src="images/3.jpg"></li>
            <li><img src="images/4.jpg"></li>
            <li><img src="images/5.jpg"></li>
            <li><img src="images/6.jpg"></li>
            <li><img src="images/7.jpg"></li>
            <li><img src="images/8.jpg"></li>
            <li><img src="images/9.jpg"></li>
        </ul>
    </div>
    <script type="text/javascript">
	    var aLi = document.getElementsByTagName("li");
	    var arr = [];
	    var z = 1; //li的层级(zIndex)
	    // 1.将浮动定位改为绝对定位(注：div高度会塌陷)
	    for (var i = 0, l = aLi.length, tmp = {}; i < l; i++) {
	        tmp = {
	            left: aLi[i].offsetLeft,
	            top: aLi[i].offsetTop,
	        };
	        arr.push(tmp);
	    }
	    for (var i = 0, l = aLi.length; i < l; i++) {
	    	aLi[i].index = i;
	        aLi[i].style.position = "absolute";
	        aLi[i].style.left = arr[i].left + 'px';
	        aLi[i].style.top = arr[i].top + 'px';
	        aLi[i].style.margin = 0;
	    }
	    // 2.拖拽功能
	    for (var i = 0, l = aLi.length; i < l; i++) {
	        drag(aLi[i]);
	    }
	    function drag(obj) {
	        // 给该对象绑定鼠标按下事件
	        obj.onmousedown = function(ev) {
	            //console.log(this);//当前作用域，这里表示按下去的那个li
	            //console.log(arguments);
	            var ev = ev || widows.event;
	            //获取当前鼠标点击位置
	            var x = ev.clientX;
	            var y = ev.clientY;
	            // 获取当前图片位置
	            var left = this.offsetLeft;
	            var top = this.offsetTop;
	            //设置li的层级不断的往上加
	            this.style.zIndex = z++;
	            // 移动过程中
	            document.onmousemove = function(ev) {
	                    var ev = ev || widows.event;
	                    //获取移动过程中的位置，然后减去点击时的位置，最后在上图片原来的位置就是移动后图片的位置
	                    var _left = ev.clientX - x + left;
	                    var _top = ev.clientY - y + top;
	                    obj.style.left = _left + 'px';
	                    obj.style.top = _top + 'px';
	                    //移动过程中碰撞检测函数
	                    // console.log(oLi);
	                    // 先把全部的都去掉边框
	                    for (var i = 0, l = aLi.length; i < l; i++) {
	                        aLi[i].style.border = "2px solid transparent";
	                    }
	                    //然后检测碰撞
	                    var oLi = nearLi(obj);
	                    if (oLi) {
	                        oLi.style.border = "2px solid red";
	                       
	                    }

	                }
	                //当鼠标抬起的时候，需要把鼠标松开事件改为null
	            document.onmouseup = function() {
	                    document.onmousemove = null;
	                    document.onmouseup = null;
	                    // 抬起来的时候再次获取碰撞的数据
	                    var oLi = nearLi(obj);
	                    if(oLi){
	                    	//交换位置
	                    	// obj.style.left = arr[oLi.index].left+"px";
	                    	// obj.style.top = arr[oLi.index].top+"px";
	                    	// oLi.style.left = arr[obj.index].left+"px";
	                    	// oLi.style.top = arr[obj.index].top+"px";
	                    	animate(obj, {left: arr[oLi.index].left, top: arr[oLi.index].top},10, 0.08);
	                    	animate(oLi, {left: arr[obj.index].left, top: arr[obj.index].top},10, 0.08);
	                    	//清楚交换的边框
	                    	oLi.style.border = "2px solid transparent";
	                    	//交换索引
	                    	var temp = obj.index;
	                    	obj.index = oLi.index;
	                    	oLi.index = temp;
	                    }else{
	                    	animate(obj, {left: arr[obj.index].left, top: arr[obj.index].top},10, 0.08);
	                    	// obj.style.left = arr[obj.index].left+"px";
	                    	// obj.style.top = arr[obj.index].top+"px";
	                    }

	                }
	                //返回false是为了屏蔽h5中图片标签<img>默认的拖拽事件
	            return false;
	        }

	    }
	    // 3.碰撞检查
	    function impact(obj1, obj2) {
	        //对象1的各各边距 
	        var left1 = obj1.offsetLeft; //左边距
	        var top1 = obj1.offsetTop; //上边距
	        var right1 = left1 + obj1.offsetWidth; //对象右边距离屏幕左边的距离
	        var bottom1 = top1 + obj1.offsetHeight; //对象下边距离屏幕顶端的距离
	        //对象2的各各边距
	        var left2 = obj2.offsetLeft;
	        var top2 = obj2.offsetTop;
	        var right2 = left2 + obj2.offsetWidth;
	        var bottom2 = top2 + obj2.offsetHeight;

	        if (right1 < left2 || bottom1 < top2 || left1 > right2 || top1 > bottom2) {
	            //console.log("不成功")
	            // 不成功
	            return false;
	        } else {
	            //console.log("成功")
	            //成功
	            return true;
	        }
	    }
	    //计算最小距离
	    function nearLi(obj) {
	        var n = 10000000000;
	        var oLi = '';
	        for (var j = 0, l = aLi.length; j < l; j++) {
	            if (obj != aLi[j] && impact(obj, aLi[j])) {
	                // 计算碰撞的li距离
	                var c = distance(obj, aLi[j]);
	                if (c < n) {
	                    n = c;
	                    oLi = aLi[j];
	                }

	            }
	        }
	        return oLi;
	    }
	    //勾股定理计算斜边
	    function distance(obj1, obj2) {
	        var a = obj1.offsetLeft - obj2.offsetLeft;
	        var b = obj1.offsetTop - obj2.offsetTop;
	        return Math.sqrt(a * a + b * b);
	    }
    </script>
</body>

</html>
